﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace AssemblyExplorer
{
    public partial class MainForm : Form
    {
        AssemblyDataProvider _provider;
        public MainForm()
        {
            InitializeComponent();
            _provider = new AssemblyDataProvider();

            view1.DataProvider = _provider;
            view1.ImageList = Icons.ImageList;
            view1.Activate();
        }

        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Assembly files|*.dll;*.exe";
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                _provider.LoadAssembly(dlg.FileName);
                view1.Activate();
            }
        }

        private void ApplyDescriptionSettings(StrategySettings settings, 
            IDescriptionStrategy descriptionStrategy)
        {
            switch (settings.StrategyOption)
            {
                case StrategyOption.Default:
                    _provider.DescriptionStrategy = new DefaultDescriptionStrategy();
                    break;
                case StrategyOption.Plugin:
                    if (descriptionStrategy != null)
                    {
                        _provider.DescriptionStrategy = descriptionStrategy;
                    }
                    else
                    {
                        try
                        {
                            Assembly assembly = Assembly.LoadFrom(settings.PluginAssembly);
                            IDescriptionPlugin plugin = (IDescriptionPlugin)assembly.CreateInstance(settings.PluginType);
                            plugin.LoadState(settings.PluginState);
                            _provider.DescriptionStrategy = plugin.DescriptionStrategy;
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }
                    }
                    break;
                case StrategyOption.UserCode:
                    {
                        try
                        {
                            var result = ReflectionHelper.Compile(settings.UserProvidedCode);
                            Assembly assembly = result.CompiledAssembly;
                            string[] pluginTypes = ReflectionHelper.GetTypesByInterface(assembly, typeof(IDescriptionStrategy));
                            if (pluginTypes.Length > 0)
                            {
                                IDescriptionStrategy strategy = (IDescriptionStrategy)assembly.CreateInstance(pluginTypes[0]);
                                _provider.DescriptionStrategy = strategy;
                            }
                            else
                            {
                                MessageBox.Show("No types found with IDescriptionStrategy interface in provided code");
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }
                    }
                    break;
            }
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmSettings frm = new frmSettings();
            frm.Owner = this;
            frm.BindingFlags = _provider.BindingFlags;
            StrategySettings descriptionSettings = new StrategySettings();
            descriptionSettings.LoadXml(Properties.Settings.Default.DescriptionStrategySettings);
            frm.DescriptionStrategySettings = descriptionSettings;

            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                _provider.BindingFlags = frm.BindingFlags;
                ApplyDescriptionSettings(frm.DescriptionStrategySettings, frm.DescriptionStrategy);
                Properties.Settings.Default.DescriptionStrategySettings = frm.DescriptionStrategySettings.GetXml();
                Properties.Settings.Default.Save();
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            StrategySettings descriptionSettings = new StrategySettings();
            descriptionSettings.LoadXml(Properties.Settings.Default.DescriptionStrategySettings);
            ApplyDescriptionSettings(descriptionSettings, null);
        }
    }
}
